package com.shenghui.enterprise.base.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.shenghui.enterprise.base.entity.*;
import com.shenghui.enterprise.utils.GeneralUtil;
import com.shenghui.enterprise.vo.Result;
import com.shenghui.enterprise.base.mapper.BaseModuleMapper;
import com.shenghui.enterprise.base.mapper.BaseRoleMapper;
import com.shenghui.enterprise.base.mapper.BaseRoleModuleMapper;
import com.shenghui.enterprise.base.service.IBaseRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description: 角色管理业务逻辑实现类
 * @Author houjh
 * @Email: happyxiaohou@gmail.com
 * @Date: 2020-05-29
 * @Copyright (c) 2020-2022 云南昇晖科技有限公司
 */
@Service
@Transactional
public class BaseRoleServiceImpl extends ServiceImpl<BaseRoleMapper, BaseRole> implements IBaseRoleService {
    @Autowired
    private BaseRoleMapper roleMapper;
    @Autowired
    private BaseRoleModuleMapper roleModuleMapper;
    @Autowired
    private EntityCommon entityCommon;
    @Autowired
    private BaseModuleMapper moduleMapper;

    /**
     * 查询角色列表信息数据
     * @param map
     * @return
     */
    @Override
    public Object getBaseRoleList(Map map) {
        Page<Map> mapPage = new Page<>(map);
        IPage iPage = roleMapper.selectPage(mapPage, new QueryWrapper<BaseRole>()
                .lambda()
                .like(GeneralUtil.isNotNull(map.get("name")), BaseRole::getName, map.get("name")));
        return new PageModel(iPage.getTotal(), iPage.getRecords());
    }

    @Override
    @Transactional
    public Result deleteBaseRole(String id) {
        String message = "角色删除成功!";
        //删除角色信息
        int i = roleMapper.deleteById(id);
        //删除角色和角色的关联关系表
        Map<String,Object> params = new HashMap<>();
        params.put("role_id", id);
        int j = roleModuleMapper.deleteByMap(params);
        return Result.ok(message);
    }

    @Override
    @Transactional
    public Result updateBaseRoleOrder(String id, Integer orderValue) {
        if(StringUtils.isEmpty(id)){
            return Result.error("必填参数【id】不能为空");
        }
        if(StringUtils.isEmpty(orderValue)){
            return Result.error("必填参数【orderValue】不能为空");
        }
        String message = "角色排序值修改失败！";
        BaseRole role = new BaseRole();
        role.setRoleId(id);
        role.setOrderValue(orderValue);
        int i = roleMapper.updateById(role);
        if (i > 0) {
            message = "角色排序值修改成功！";
        }
        return Result.ok( message);
    }

    @Override
    public Object getAuthorTree(String roleId, HttpServletRequest request, Map map) {
        //获取当前登录用户有权限的所有模块信息
        String parentId = null;
        if (GeneralUtil.isNotNull(map.get("id"))) {
            parentId = map.get("id").toString();
        }

        List<Map> list = moduleMapper.getBaseModuleTreeList(parentId);
        if (list != null && list.size() > 0) {
            for (Map m : list) {
                //获取模块是不是有子集
                parentId = m.get("moduleId").toString();
                List<Map> result = moduleMapper.getBaseModuleTreeList(parentId);
                if(result != null && result.size() > 0){
                    m.put("isParent", true);
                } else {
                    m.put("isParent", false);
                }
                List<BaseRoleModule> maps = roleModuleMapper.selectList(new QueryWrapper<BaseRoleModule>()
                        .lambda().eq(BaseRoleModule::getModuleId, m.get("moduleId").toString())
                        .eq(BaseRoleModule::getRoleId, roleId)
                );
                if (GeneralUtil.isNotNull(maps) && maps.size() > 0) {
                    m.put("checked", true);
                } else {
                    m.put("checked", false);
                }
                m.put("id", m.get("moduleId"));
                m.put("name" , m.get("name"));
                m.put("orderValue", m.get("orderValue"));
                m.put("parentId", m.get("parentId"));
            }
        }
        return list;
    }

    /**
     * 添加角色授权信息
     * @param
     * @return
     */
    @Override
    @Transactional
    public Result addAuthorize(String roleId, String moduleId) {
        if (StringUtils.isEmpty(roleId)) {
            return Result.error("必须参数【roleId】不能为空!");
        }
        if (StringUtils.isEmpty(moduleId)) {
            return Result.error("必须参数【moduleId】不能为空!");
        }
        //从模块角色关系表中删除moduleId的所有记录
        List<String> midList = getAllModuleIds(moduleId, new ArrayList<>());
        //找出所有父级模块
        List<String> parentIds = getAllParentIds(moduleId, new ArrayList<>(),true);
        if (parentIds != null && parentIds.size() > 0){
            midList.addAll(parentIds);
        }
        deleteRoleModule(roleId, midList);
        //添加新的模块角色数据到关系表中
        for (String mId : midList) {
            BaseRoleModule rm = new BaseRoleModule();
            entityCommon.createBase(rm);
            rm.setModuleId(mId);
            rm.setRoleId(roleId);
            roleModuleMapper.insert(rm);
        }
        return Result.ok("授权成功!");
    }

    /**
     * 取消角色授权信息
     * @param roleId
     * @return
     */
    @Override
    public Result cancelAuthorize(String roleId, String moduleId) {
        if (StringUtils.isEmpty(roleId)) {
            return Result.error("必须参数【roleId】不能为空!");
        }
        if (StringUtils.isEmpty(moduleId)) {
            return Result.error("必须参数【moduleId】不能为空!");
        }
        //从模块角色关系表中删除moduleId的所有记录
        List<String> midList = getAllModuleIds(moduleId, new ArrayList<>());
        deleteRoleModule(roleId, midList);
        return Result.ok("取消成功!");
    }

    @Override
    @Transactional
    public Result addBaseRole(BaseRole role, String id) {
        JSONObject json = new JSONObject();
        String action_msg = "本次操作失败！";
        if (GeneralUtil.isNull(id)) {
            entityCommon.createBase(role);
            int i = roleMapper.insert(role);
            if (i > 0) {
                action_msg = "角色添加成功";
            }
        } else {
            role.setRoleId(id);
            int i = roleMapper.updateById(role);
            if (i > 0) {
                action_msg = "角色修改成功";
            }
        }
        return Result.ok(action_msg, role);
    }

    @Override
    public BaseRole getBaseRoleById(String id) {
        return roleMapper.selectById(id);
    }

    /**
     * 根据角色ID 查询所有子集ID
     * @param roleId
     * @param idList
     * @return
     */
    @Override
    public List<String> getChildRoleIdByParentId(String roleId, List<String> idList){
        idList.add(roleId);
        return idList;
    }

    /**
     * 获取所有节点ID
     * @param moduleId
     * @param idList
     * @return
     */
    private List<String> getAllModuleIds(String moduleId,List<String> idList){
        idList.add(moduleId);
        List<BaseModule> modules = moduleMapper.selectList(new QueryWrapper<BaseModule>().lambda().eq(BaseModule::getParentId, moduleId));
        if (modules != null && modules.size() > 0) {
            for (BaseModule bm : modules) {
                getAllModuleIds(bm.getModuleId(), idList);
            }
        }
        return idList;
    }

    /**
     * 获取所有父级ID
     * @param moduleId
     * @param idList
     * @return
     */
    private List<String> getAllParentIds(String moduleId,List<String> idList,boolean isFirst){
        if(!isFirst){
            idList.add(moduleId);
        }
        BaseModule module = moduleMapper.selectById(moduleId);
        if(!"0".equals(module.getParentId())){
            getAllParentIds(module.getParentId(), idList, false);
        }
        return idList;
    }

    /**
     * 刪除角色与模块关联信息
     * @param roleId
     * @param midList
     */
    private void deleteRoleModule(String roleId,List<String> midList){
        for (String mId : midList) {
            roleModuleMapper.delete(new QueryWrapper<BaseRoleModule>().lambda().eq(BaseRoleModule::getModuleId, mId).eq(BaseRoleModule::getRoleId, roleId));
        }
    }
}
